// 《围棋》作者版权所有。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package abi

import "unsafe"

// RegArgs是一个结构，在当前体系结构上，每个参数都有空间
// 和返回值寄存器。
// 
// 汇编代码知道RegArgs的前两个字段
// 的布局。
// 
// RegArgs还包含用于保存指针的额外空间
// 如果仅将指针保留在整数
// 寄存器空间中可能不安全，则会增加空间。
type RegArgs struct {
	Ints   [IntArgRegs]uintptr  // 非类型化整数寄存器
	Floats [FloatArgRegs]uint64 // 非类型化浮点寄存器

	// 程序集已知此点以上的字段。

	// Ptrs是一个复制int但具有指针类型的空间，
	// 用于使在寄存器中传递或返回的指针
	// 通过使类型不安全而对GC可见。
	Ptrs [IntArgRegs]unsafe.Pointer

	// ReturnIsPtr是一个位图，指示哪个寄存器
	// 包含或将包含来自
	// 反射调用的返回路径上的指针。第i位指示第i个
	// 寄存器是否包含或将包含有效的Go指针。
	ReturnIsPtr IntArgRegBitmap
}

// IntArgRegBitmap是一种足够大的位图，每个
// 整型参数/返回寄存器可容纳一位。
type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8

// Set将位图的第i位设置为1。
func (b *IntArgRegBitmap) Set(i int) {
	b[i/8] |= uint8(1) << (i % 8)
}

// Get返回位图的第i位是否已设置。
// 
// nosplit，因为它是在非常敏感的上下文中调用的，比如反射调用返回路径上的
// 。
// 
// go:nosplit 
func (b *IntArgRegBitmap) Get(i int) bool {
	return b[i/8]&(uint8(1)<<(i%8)) != 0
}

// FuncPC*内部函数。
// 
// 注意：在带有插件的程序中，FuncPC*可以为同一个函数返回不同的值
// 因为地址空间中实际上有同一函数的多个副本。为了安全起见，不要在任何==表达式中使用此函数的
// 结果。
// 使用结果作为开始执行代码的地址是安全的。

// FuncPCABI0返回函数f的条目PC，该条目必须是定义为ABI0的函数的
// 直接引用。否则这是一个
// 编译时错误。
// 
// 作为编译内在实现。
func FuncPCABI0(f interface{}) uintptr

// FuncPCABIInternal返回函数f的输入PC。如果f是
// 函数的直接引用，则必须将其定义为ABIInternal。
// 否则为编译时错误。如果f不是已定义函数的直接引用
// ，则假定f是func值。否则
// 行为未定义。
// 
// 作为编译内在实现。
func FuncPCABIInternal(f interface{}) uintptr
